package easier.app.x;

import android.Manifest.permission;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Service;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.location.LocationManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Environment;
import android.os.Vibrator;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresPermission;
import androidx.arch.core.util.Function;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsControllerCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.Adapter;
import easier.app.x.result.Permission;
import easier.app.x.result.ResultFragment;
import easier.app.x.result.ResultFragmentFactory;
import easier.app.x.view.EditInputManager;
import easier.app.x.view.SystemUi;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;

public class CommonCode {

    /**
     * 缓存数组
     */
    private static char[] chars;

    /**
     * @return 创建数字和字母组合的数组
     */
    private static char[] getChars() {

        if ( chars == null ) {
            chars = numberAndLetter();
        }
        return chars;
    }

    /**
     * @param window  设置状态栏文字颜色
     * @param isLight true:亮色模式,文字黑色
     */
    public static void setStatusBarsLight( Window window, boolean isLight ) {

        WindowInsetsControllerCompat controller = ViewCompat
            .getWindowInsetsController( window.getDecorView() );
        if ( controller != null ) {
            controller.setAppearanceLightStatusBars( isLight );
        }
    }

    /**
     * @param activity 设置状态栏文字颜色
     * @param isLight  true:亮色模式,文字黑色
     */
    public static void setStatusBarsLight( Activity activity, boolean isLight ) {

        setStatusBarsLight( activity.getWindow(), isLight );
    }

    /**
     * @param context 获取状态栏高度
     *
     * @return 状态栏高度
     */
    public static int getStatusBarHeight( Context context ) {

        return SystemUi.getStatusBarHeight( context );
    }

    public static void setStatusBarHeight( Context context, View statusBar ) {

        LayoutParams layoutParams = statusBar.getLayoutParams();
        if ( layoutParams != null ) {
            layoutParams.height = getStatusBarHeight( context );
        }
    }

    /**
     * @param context  转换dp为pix
     * @param sizeInDp dp
     *
     * @return pix
     */
    public static float applyDp( Context context, float sizeInDp ) {

        return TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, sizeInDp, context.getResources().getDisplayMetrics() );
    }

    /**
     * @param tag 创建一个唯一标识
     *
     * @return 唯一标识
     */
    public static String timedUUID( String tag ) {

        return tag + timedUUID();
    }

    /**
     * @return 唯一标识
     */
    public static String timedUUID() {

        return System.currentTimeMillis() + UUID.randomUUID().toString();
    }

    /**
     * @return 唯一标识
     */
    public static String UUID() {

        return UUID.randomUUID().toString();
    }

    /**
     * 1.生成的字符串每个位置都有可能是str中的一个字母或数字，需要导入的包是import java.util.Random;
     *
     * @param length 需要生成的长度
     *
     * @return 随机字符串
     */
    public static String randomString( int length ) {

        /* 1.创建字符组 */
        char[] result = getChars();

        /* 2.打乱字符组顺序 */
        Random random = new Random();
        for ( int i = 0; i < result.length; i++ ) {
            int j = random.nextInt( result.length );
            char c = result[i];
            result[i] = result[j];
            result[j] = c;
        }

        /* 3.随机读取 */
        StringBuilder stringBuilder = new StringBuilder();
        for ( int i = 0; i < length; i++ ) {
            int k = random.nextInt();
            k = Math.abs( k );
            int index = k % result.length;
            char c = result[index];
            stringBuilder.append( c );
        }

        return stringBuilder.toString();
    }

    /**
     * @return 创建一组字符串
     */
    public static char[] numberAndLetter() {

        char[] result = new char[62];
        for ( int i = 0; i < 10; i++ ) {

            result[i] = (char) (i + 48);
        }
        for ( int i = 0; i < 26; i++ ) {
            result[i + 10] = (char) (i + 65);
        }
        for ( int i = 0; i < 26; i++ ) {
            result[i + 36] = (char) (i + 97);
        }
        return result;
    }

    /**
     * @param context 显示toast
     * @param msg     消息
     */
    public static void showToast( Context context, String msg ) {

        Toast.makeText( context, msg, Toast.LENGTH_SHORT ).show();
    }

    /**
     * @param context 显示toast
     * @param msg     消息
     */
    public static void showToastLong( Context context, String msg ) {

        Toast.makeText( context, msg, Toast.LENGTH_LONG ).show();
    }

    /**
     * @param decimal 数字去掉尾部0
     *
     * @return 去0
     */
    public static String stripZeros( BigDecimal decimal ) {

        return decimal.stripTrailingZeros().toPlainString();
    }

    public static String stripZeros( BigDecimal decimal, int weishu ) {

        return decimal.setScale( weishu, BigDecimal.ROUND_HALF_UP ).stripTrailingZeros().toPlainString();
    }

    /**
     * @param context 拨打电话
     * @param phone   电话
     */
    public static void call( Context context, String phone ) {

        if ( !TextUtils.isEmpty( phone ) ) {
            Intent intent = new Intent( Intent.ACTION_DIAL, Uri.parse( "tel:" + phone ) );
            intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
            context.startActivity( intent );
        } else {
            Intent intent = new Intent( Intent.ACTION_DIAL );
            intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
            context.startActivity( intent );
        }
    }

    /**
     * 通知recycler刷新
     *
     * @param recyclerView recycler
     * @param position     刷新位置
     */
    public static void notifyItemChanged( RecyclerView recyclerView, int position ) {

        if ( position < 0 ) {
            return;
        }

        Adapter< ? > adapter = recyclerView.getAdapter();
        if ( adapter != null ) {
            adapter.notifyItemChanged( position );
        }
    }

    /**
     * 通知recycler刷新
     *
     * @param recyclerView recycler
     * @param position     刷新位置
     */
    public static void notifyItemChanged( RecyclerView recyclerView, int position, Object payLoad ) {

        if ( position < 0 ) {
            return;
        }

        Adapter< ? > adapter = recyclerView.getAdapter();
        if ( adapter != null ) {
            adapter.notifyItemChanged( position, payLoad );
        }
    }

    /**
     * 检查通知是否打开
     *
     * @param context context
     *
     * @return true:已经打开
     */
    public static boolean areNotificationsEnabled( Context context ) {

        return NotificationManagerCompat.from( context ).areNotificationsEnabled();
    }

    /**
     * @param context 打开应用通知设置界面
     */
    public static void openNotificationSetting( Context context ) {

        Intent intent = new Intent();
        if ( VERSION.SDK_INT >= VERSION_CODES.O ) {
            intent.setAction( Settings.ACTION_APP_NOTIFICATION_SETTINGS );
            //这种方案适用于 API 26, 即8.0（含8.0）以上可以用
            intent.putExtra( Settings.EXTRA_APP_PACKAGE, context.getPackageName() );
            intent.putExtra( Settings.EXTRA_CHANNEL_ID, context.getApplicationInfo().uid );

            //这种方案适用于 API21——25，即 5.0——7.1 之间的版本可以使用
            intent.putExtra( "app_package", context.getPackageName() );
            intent.putExtra( "app_uid", context.getApplicationInfo().uid );

            ComponentName componentName = intent.resolveActivity( context.getPackageManager() );
            if ( componentName != null ) {
                context.startActivity( intent );
            } else {
                intent.setAction( Settings.ACTION_APPLICATION_DETAILS_SETTINGS );
                Uri uri = Uri.fromParts( "package", context.getPackageName(), null );
                intent.setData( uri );
                context.startActivity( intent );
            }
        }
    }

    /**
     * 打开应用通知设置界面,并且获取设置结果
     *
     * @param activity Activity
     * @param callback 回调
     */
    public static void openNotificationSetting( FragmentActivity activity, ActivityResultCallback< Boolean > callback ) {

        ResultFragment< Void, Void > fragment = ResultFragmentFactory.buildNotificationSetting( activity, callback );
        activity.getSupportFragmentManager().beginTransaction().add( fragment, "openNotificationSetting" ).commit();
    }

    /**
     * @param context 检查定位是否已经开启
     *
     * @return true:开启了
     */
    public static boolean isLocationEnabled( Context context ) {

        LocationManager locationManager = (LocationManager) context.getSystemService( Context.LOCATION_SERVICE );
        boolean gps = locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER );
        boolean network = locationManager.isProviderEnabled( LocationManager.NETWORK_PROVIDER );
        return gps || network;
    }

    /**
     * 检查去权限
     *
     * @param context    context
     * @param permission 权限
     *
     * @return 检查结果
     */
    public static boolean checkPermission( Context context, String permission ) {

        return Permission.check( context, permission );
    }

    /**
     * 检查是否可以定位,包括权限和开关
     *
     * @param context context
     *
     * @return true:可以定位
     */
    public static boolean couldLocation( Context context ) {

        if ( checkPermission( context, permission.ACCESS_FINE_LOCATION ) || checkPermission( context,
            permission.ACCESS_COARSE_LOCATION ) ) {
            return isLocationEnabled( context );
        }
        return false;
    }

    /**
     * 复制数据到剪贴板
     *
     * @param context context
     * @param tag     tag
     * @param data    数据
     */
    public static void copyData( Context context, String tag, String data ) {

        ClipboardManager cm = (ClipboardManager) context.getSystemService(
            Context.CLIPBOARD_SERVICE );
        ClipData mClipData = ClipData.newPlainText( tag, data );
        cm.setPrimaryClip( mClipData );
    }

    /**
     * 保存图片到文件
     *
     * @param bitmap 图片
     * @param file   文件
     */
    public static boolean saveBitmap( Bitmap bitmap, File file ) {

        try {
            FileOutputStream outputStream = null;
            outputStream = new FileOutputStream( file );
            bitmap.compress( CompressFormat.PNG, 100, outputStream );
            outputStream.flush();
            outputStream.close();
            return true;
        } catch ( IOException e ) {
            if ( BuildConfig.DEBUG ) {
                e.printStackTrace();
            }
            return false;
        }
    }

    /**
     * 创建临时文件
     *
     * @param context context
     * @param prefix  前缀
     * @param suffix  后缀
     *
     * @return 临时文件
     */
    @Nullable
    public static File createTempFile( Context context, String prefix, String suffix ) {

        File parent;
        if ( Environment.MEDIA_MOUNTED.equals( Environment.getExternalStorageState() ) ) {
            parent = context.getExternalCacheDir();
        } else {
            parent = context.getCacheDir();
        }

        try {
            File tempFile = File.createTempFile( prefix, suffix, parent );
            tempFile.deleteOnExit();
            return tempFile;
        } catch ( IOException e ) {
            if ( BuildConfig.DEBUG ) {
                e.printStackTrace();
            }
            return null;
        }
    }

    /**
     * 保存{@link Uri}到文件
     *
     * @param uri  地址
     * @param file 文件
     *
     * @return true:成功
     */
    public static boolean copyFromUri( Context context, Uri uri, File file ) {

        try {
            InputStream inputStream = null;
            inputStream = context.getContentResolver().openInputStream( uri );

            OutputStream outputStream = null;
            outputStream = new FileOutputStream( file );

            return copyStream( inputStream, outputStream );
        } catch ( FileNotFoundException e ) {
            if ( BuildConfig.DEBUG ) {
                e.printStackTrace();
            }
            return false;
        }
    }

    /**
     * 保存{@link Uri}到文件
     *
     * @param uri 地址
     *
     * @return true:成功
     */
    public static File copyFromUri( Context context, Uri uri, String prefix, String suffix ) {

        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {

            inputStream = context.getContentResolver().openInputStream( uri );
            if ( inputStream == null ) {
                return null;
            }

            File file = createTempFile( context, prefix, suffix );
            if ( file == null ) {
                return null;
            }
            outputStream = new FileOutputStream( file );

            boolean b = copyStream( inputStream, outputStream );

            if ( b ) {
                return file;
            } else {
                /* 可能写入一半失败了,删除掉 */
                if ( file.exists() ) {
                    boolean delete = file.delete();
                    if ( !delete ) {
                        file.deleteOnExit();
                    }
                }
                return null;
            }

        } catch ( FileNotFoundException e ) {
            if ( BuildConfig.DEBUG ) {
                e.printStackTrace();
            }
            return null;
        }
    }

    /**
     * 复制数据流
     *
     * @param input  输入
     * @param output 输出
     *
     * @return true:复制成功
     */
    public static boolean copyStream( InputStream input, OutputStream output ) {

        final int BUFFER_SIZE = 1024 * 4;
        byte[] buffer = new byte[BUFFER_SIZE];
        int n = 0;
        try (
            BufferedInputStream in = new BufferedInputStream( input, BUFFER_SIZE );
            BufferedOutputStream out = new BufferedOutputStream( output, BUFFER_SIZE )
        ) {
            while ( (n = in.read( buffer, 0, BUFFER_SIZE )) != -1 ) {
                out.write( buffer, 0, n );
            }
            out.flush();
            return true;
        } catch ( Exception e ) {
            if ( BuildConfig.DEBUG ) {
                e.printStackTrace();
            }
            return false;
        }
    }

    /**
     * 获取APP版本
     */
    public static String getVersionName( Context context ) {

        PackageManager packageManager = context.getPackageManager();
        PackageInfo packageInfo;
        String versionName = "";
        try {
            packageInfo = packageManager.getPackageInfo( context.getPackageName(), 0 );
            versionName = packageInfo.versionName;
        } catch ( PackageManager.NameNotFoundException e ) {
            e.printStackTrace();
        }
        return versionName;
    }

    /**
     * 获取APP版本
     */
    public static int getVersionCode( Context context ) {

        PackageManager packageManager = context.getPackageManager();
        PackageInfo packageInfo;
        try {
            packageInfo = packageManager.getPackageInfo( context.getPackageName(), 0 );
            return packageInfo.versionCode;
        } catch ( PackageManager.NameNotFoundException e ) {
            e.printStackTrace();
        }
        return 0;
    }

    public static long convertFormatTimeToCalendar( String time, String format ) throws Exception {

        @SuppressLint( "SimpleDateFormat" )
        SimpleDateFormat sdf = new SimpleDateFormat( format );
        Date parse = sdf.parse( time );
        if ( parse != null ) {
            return parse.getTime();
        }

        throw new Exception();
    }

    @SuppressLint( "DefaultLocale" )
    public static String getTimeStyleYMD( Calendar calendar ) {

        int timeYear = calendar.get( Calendar.YEAR );
        int timeMonth = calendar.get( Calendar.MONTH ) + 1;
        int timeDay = calendar.get( Calendar.DAY_OF_MONTH );

        return String.format( "%d-%d-%d", timeYear, timeMonth, timeDay );
    }

    @SuppressLint( "DefaultLocale" )
    public static String getTime( Calendar calendar ) {

        int timeYear = calendar.get( Calendar.YEAR );
        int timeMonth = calendar.get( Calendar.MONTH ) + 1;
        int timeDay = calendar.get( Calendar.DAY_OF_MONTH );
        int hour = calendar.get( Calendar.HOUR_OF_DAY );
        int minute = calendar.get( Calendar.MINUTE );
        int second = calendar.get( Calendar.SECOND );
        int milliSecond = calendar.get( Calendar.MILLISECOND );
        if ( milliSecond > 0 ) {
            return String.format( "%d-%02d-%02d %02d:%02d:%02d.%04d", timeYear, timeMonth, timeDay, hour, minute, second,
                milliSecond );
        } else {
            return String.format( "%d-%02d-%02d %02d:%02d:%02d", timeYear, timeMonth, timeDay, hour, minute, second );
        }
    }

    @SuppressLint( "DefaultLocale" )
    public static String getTimeFromSecond( String time ) {

        try {
            long l = Long.parseLong( time ) * 1000;
            Date date = new Date( l );
            Calendar calendar = Calendar.getInstance();
            calendar.setTime( date );

            int timeYear = calendar.get( Calendar.YEAR );
            int timeMonth = calendar.get( Calendar.MONTH ) + 1;
            int timeDay = calendar.get( Calendar.DAY_OF_MONTH );
            int hour = calendar.get( Calendar.HOUR_OF_DAY );
            int minute = calendar.get( Calendar.MINUTE );
            int second = calendar.get( Calendar.SECOND );

            return String.format( "%d-%02d-%02d %02d:%02d:%02d", timeYear, timeMonth, timeDay, hour, minute, second );
        } catch ( Exception e ) {
            e.printStackTrace();
            return "非法时间";
        }
    }

    @SuppressLint( "DefaultLocale" )
    public static String getTimeFromMillSecond( String time ) {

        try {
            long l = Long.parseLong( time );
            Date date = new Date( l );
            Calendar calendar = Calendar.getInstance();
            calendar.setTime( date );

            int timeYear = calendar.get( Calendar.YEAR );
            int timeMonth = calendar.get( Calendar.MONTH ) + 1;
            int timeDay = calendar.get( Calendar.DAY_OF_MONTH );
            int hour = calendar.get( Calendar.HOUR_OF_DAY );
            int minute = calendar.get( Calendar.MINUTE );
            int second = calendar.get( Calendar.SECOND );
            int milliSecond = calendar.get( Calendar.MILLISECOND );

            return String.format( "%d-%02d-%02d %02d:%02d:%02d.%04d", timeYear, timeMonth, timeDay, hour, minute, second,
                milliSecond );
        } catch ( Exception e ) {
            e.printStackTrace();
            return "非法时间";
        }
    }

    /**
     * 设置时间到 当前日期:23:59:59:999
     */
    public static void setCalendarToCurrentEnd( Calendar calendar ) {

        calendar.set( calendar.get( Calendar.YEAR ), calendar.get( Calendar.MONTH ), calendar.get( Calendar.DATE ), 23, 59, 59 );
        calendar.set( Calendar.MILLISECOND, 999 );

    }

    /**
     * 设置时间到 当前日期:00:00:00:0
     */
    public static void setCalendarToCurrentStart( Calendar calendar ) {

        calendar.set( calendar.get( Calendar.YEAR ), calendar.get( Calendar.MONTH ), calendar.get( Calendar.DATE ), 0, 0, 0 );
        calendar.set( Calendar.MILLISECOND, 0 );
    }

    /**
     * 将一个秒单位的数字转换成XXX:XX:XX这种形式的字符串
     *
     * @param timeInSecond 秒数
     *
     * @return 转换成字符
     */
    @SuppressLint( "DefaultLocale" )
    public static String getFormatCountDownTime( long timeInSecond ) {

        long hour = timeInSecond / 60 / 60;
        long minutes = (timeInSecond - (hour * 60 * 60)) / 60;
        long seconds = (timeInSecond - (hour * 60 * 60) - minutes * 60);
        return String.format( "%d:%02d:%02d", hour, minutes, seconds );
    }

    public static DisplayMetrics getDisplayMetrics( Context context ) {

        return context.getResources().getDisplayMetrics();
    }

    public static int getDisplayWidth( Context context ) {

        return getDisplayMetrics( context ).widthPixels;
    }

    public static int getDisplayHeight( Context context ) {

        return getDisplayMetrics( context ).heightPixels;
    }

    public static void setMargin( View view, int start, int end, int top, int bottom ) {

        LayoutParams layoutParams = view.getLayoutParams();
        if ( layoutParams instanceof MarginLayoutParams ) {
            MarginLayoutParams params = (MarginLayoutParams) layoutParams;
            Context context = view.getContext();

            params.setMarginStart( (int) applyDp( context, start ) );
            params.setMarginEnd( (int) applyDp( context, end ) );
            params.topMargin = (int) applyDp( context, top );
            params.bottomMargin = (int) applyDp( context, bottom );
        }
    }

    public static void registerForActivityResult(
        FragmentManager manager,
        Intent intent,
        ActivityResultCallback< ActivityResult > callback ) {

        ResultFragment< Intent, ActivityResult > fragment = ResultFragmentFactory.buildRegisterForActivityResult(
            intent, callback );
        manager.beginTransaction().add( fragment, "registerForActivityResult" ).commit();
    }

    /**
     * @param view 隐藏软键盘
     */
    public static void hideKeyboard( View view ) {

        if ( view == null ) {
            return;
        }

        InputMethodManager imm = (InputMethodManager) view.getContext()
            .getSystemService( Context.INPUT_METHOD_SERVICE );
        if ( imm == null ) {
            return;
        }

        if ( view.getContext() instanceof Activity ) {
            View currentFocus = ((Activity) view.getContext()).getCurrentFocus();
            if ( currentFocus != null ) {
                imm.hideSoftInputFromWindow( currentFocus.getWindowToken(), 0 );
                return;
            }
        }

        imm.hideSoftInputFromWindow( view.getWindowToken(), 0 );
    }

    /**
     * Returns true if the string is null or 0-length.
     *
     * @param str the string to be examined
     *
     * @return true if str is null or zero length
     */
    public static CharSequence safeCharSequence( @Nullable CharSequence str ) {

        return TextUtils.isEmpty( str ) ? "" : str;
    }

    public static List< String > collectNotFormsSymbolsPunctuationString( CharSequence text ) {

        if ( TextUtils.isEmpty( text ) ) {
            return new ArrayList<>();
        }

        int start = -1, end = -1;/*标记非标点字符起始终止位置*/
        StringBuilder builder = new StringBuilder();
        ArrayList< String > result = new ArrayList<>();
        for ( int i = 0; i < text.length(); i++ ) {
            char c = text.charAt( i );
            if ( EditInputManager.checkFormsSymbolsPunctuation( c ) ) {
                /*找到标点了*/
                end = i;
                if ( start >= 0 ) {
                    for ( int j = start; j < end; j++ ) {
                        builder.append( text.charAt( j ) );
                    }
                    result.add( builder.toString() );
                    builder.delete( 0, builder.length() );
                    start = -1;
                }
            } else {
                if ( start == -1 ) {
                    start = i;
                }
            }
            /*最后位置不是标点,并且前面有非标点内容*/
            if ( i == text.length() - 1 && start >= 0 && start < i ) {
                for ( int j = start; j < text.length(); j++ ) {
                    builder.append( text.charAt( j ) );
                }
                result.add( builder.toString() );
                builder.delete( 0, builder.length() );
            }
        }
        return result;
    }

    /**
     * @param context 播放通知声音
     */
    public static Ringtone playRingNotification( Context context ) {

        Uri uri = RingtoneManager.getDefaultUri( RingtoneManager.TYPE_NOTIFICATION );
        Ringtone rt = RingtoneManager.getRingtone( context, uri );
        rt.play();
        return rt;
    }

    /**
     * @param context 播放紧急声音
     */
    public static Ringtone playRingAlarm( Context context ) {

        Uri uri = RingtoneManager.getDefaultUri( RingtoneManager.TYPE_ALARM );
        Ringtone rt = RingtoneManager.getRingtone( context, uri );
        rt.play();
        return rt;
    }

    /**
     * @param context 播放铃声
     */
    public static Ringtone playRingTone( Context context ) {

        Uri uri = RingtoneManager.getDefaultUri( RingtoneManager.TYPE_RINGTONE );
        Ringtone rt = RingtoneManager.getRingtone( context, uri );
        rt.play();
        return rt;
    }

    /**
     * @param context 播放铃声
     */
    public static Ringtone playRingFromUrl( Context context, Uri uri ) {

        Ringtone rt = RingtoneManager.getRingtone( context, uri );
        rt.play();
        return rt;
    }

    public static Ringtone playRingFromRaw( Context context, String rawFileName ) {

        Ringtone rt = RingtoneManager.getRingtone( context, getRawUri( context, rawFileName ) );
        rt.play();
        return rt;
    }

    /**
     * 需要权限
     * <uses-permission android:name="android.permission.VIBRATE"/>
     *
     * @param context 震动一下
     */
    @RequiresPermission( permission.VIBRATE )
    public static Vibrator playVibrate( Context context ) {

        Vibrator vibrator = (Vibrator) context.getSystemService( Service.VIBRATOR_SERVICE );
        long[] vibrationPattern = new long[]{0, 180, 80, 120};
        // 第一个参数为开关开关的时间，第二个参数是重复次数，振动需要添加权限
        vibrator.vibrate( vibrationPattern, -1 );
        return vibrator;
    }

    /**
     * @param context  context
     * @param fileName 文件名字
     *
     * @return 地址
     */
    public static Uri getRawUri( Context context, String fileName ) {

        return Uri.parse(
            ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/raw/" + fileName );
    }

    public static < T > String getListSimpleString( List< T > data, Function< T, String > function ) {

        if ( data == null || data.size() == 0 ) {
            return "";
        }
        StringBuilder builder = new StringBuilder();
        for ( int i = 0; i < data.size(); i++ ) {
            T t = data.get( i );
            builder.append( function.apply( t ) );
            if ( i < data.size() - 1 ) {
                builder.append( "," );
            }
        }
        return builder.toString();
    }

    public static Uri drawableResourceUri( Context context, int resourceId ) {

        Resources resources = context.getResources();
        return Uri.parse( ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
            resources.getResourcePackageName( resourceId ) + '/' +
            resources.getResourceTypeName( resourceId ) + '/' +
            resources.getResourceEntryName( resourceId ) );
    }
}
